package com.wzg.ttstestandroid.RealTimeVoice;

import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;


import com.baidu.speech.EventListener;
import com.baidu.speech.EventManager;
import com.baidu.speech.EventManagerFactory;
import com.baidu.speech.asr.SpeechConstant;
import com.hjq.gson.factory.GsonFactory;
import com.orhanobut.logger.Logger;

import org.json.JSONObject;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * You might think you can read it or optimize it, but no,you're wrong, Please  believe me. You'll see to do.
 * author:wzg
 * createTime: 2022/1/15/015 11:48
 * desc: 基于tts封装的语音识别功能-精简版
 * //语音识别
 */
public class RealTimeVoiceUtils {

    @SuppressLint("StaticFieldLeak")
    private static RealTimeVoiceUtils instance;

    private EventManager asr;
    private Context mContext;
    private ResultCallback callback;


    private RealTimeVoiceUtils() {
    }

    public static RealTimeVoiceUtils getInstance() {
        if (instance == null) {
            synchronized (RealTimeVoiceUtils.class) {
                if (instance == null) instance = new RealTimeVoiceUtils();
            }
        }
        return instance;
    }


    /**
     * 初始化
     */
    public void init(Context mContext) {
        this.mContext = mContext;
        asr = EventManagerFactory.create(mContext, "asr");
        asr.registerListener(listener);
    }


    /**
     * 基于SDK集成2.2 发送开始事件
     * 点击开始按钮
     * 测试参数填在这里
     */
    public void start(ResultCallback callback) {
        this.callback = callback;
        Map<String, Object> params = new LinkedHashMap<>();
        String event = SpeechConstant.ASR_START; // 替换成测试的event
        // 基于SDK集成2.1 设置识别参数
        params.put(SpeechConstant.ACCEPT_AUDIO_VOLUME, false);
        // params.put(SpeechConstant.NLU, "enable");
        // params.put(SpeechConstant.BDS_ASR_ENABLE_LONG_SPEECH, true);//长语音  优先级高于VAD_ENDPOINT_TIMEOUT
        // params.put(SpeechConstant.VAD_ENDPOINT_TIMEOUT, 0); // 长语音

        // params.put(SpeechConstant.IN_FILE, "res:///com/baidu/android/voicedemo/16k_test.pcm");
        // params.put(SpeechConstant.VAD, SpeechConstant.VAD_DNN);
        // params.put(SpeechConstant.PID, 1537); // 中文输入法模型，有逗号

        /* 语音自训练平台特有参数 */
        // params.put(SpeechConstant.PID, 8002);
        // 语音自训练平台特殊pid，8002：模型类似开放平台 1537  具体是8001还是8002，看自训练平台页面上的显示
        // params.put(SpeechConstant.LMID,1068);
        // 语音自训练平台已上线的模型ID，https://ai.baidu.com/smartasr/model
        // 注意模型ID必须在你的appId所在的百度账号下
        /* 语音自训练平台特有参数 */

        /* 测试InputStream*/
        // InFileStream.setContext(this);
        // params.put(SpeechConstant.IN_FILE,
        // "#com.baidu.aip.asrwakeup3.core.inputstream.InFileStream.createMyPipedInputStream()");

        // 请先使用如‘在线识别’界面测试和生成识别参数。 params同ActivityRecog类中myRecognizer.start(params);
        // 复制此段可以自动检测错误
        (new RealTimeVoiceAutoCheck(mContext, new Handler(Looper.getMainLooper()) {
            public void handleMessage(Message msg) {
                if (msg.what == 100) {
                    RealTimeVoiceAutoCheck realTimeVoiceAutoCheck = (RealTimeVoiceAutoCheck) msg.obj;
                    synchronized (realTimeVoiceAutoCheck) {
                        String message = realTimeVoiceAutoCheck.obtainErrorMessage(); // autoCheck.obtainAllMessage();
                        Logger.i(message + "\n");
                    }
                }
            }
        }, false)).checkAsr(params);
        String json = new JSONObject(params).toString(); // 这里可以替换成你需要测试的json
        asr.send(event, json, null, 0, 0);
        Logger.i("输入参数：" + json);
    }

    /**
     * 点击停止按钮
     * 基于SDK集成4.1 发送停止事件
     */
    public void stop() {
        Logger.i("停止识别：ASR_STOP");
        asr.send(SpeechConstant.ASR_STOP, null, null, 0, 0); //
    }


    public void pause(){
        asr.send(SpeechConstant.ASR_CANCEL, "{}", null, 0, 0);
    }
    /**
     * 销毁监听
     */
    public void dispose() {
        pause();
        asr.unregisterListener(listener);
    }

    /**
     * 监听用户说话的回调
     */
    private final EventListener listener = (s, s1, bytes, i, i1) -> {
        if (SpeechConstant.CALLBACK_EVENT_ASR_PARTIAL.equals(s)) {
            Logger.e("录音结果");
            parse(s1);
        }
    };


    /**
     * 解析用户最后一次说话的数据
     */
    private void parse(String param) {
        try {
            Logger.json(param);
            BaiDuVoice baiDuVoice = GsonFactory.getSingletonGson().fromJson(param, BaiDuVoice.class);
            Logger.e("baiduVoice : " + baiDuVoice.toString());
            //返回成功并且最终结果
            if (baiDuVoice.getError() == 0 && baiDuVoice.getResult_type().equals("final_result")) {//
                if (callback != null) {
                    callback.callback(baiDuVoice.getBest_result());
                }
            } else {//出错会跑到这里
                Logger.e("出错会跑到这里 : ");
            }
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }

    public interface ResultCallback {

        void callback(String value);
    }


}
